package com.ebraga.trackerclub.android.manager.core;

import java.util.Calendar;
import java.util.Date;

import com.ebraga.trackerclub.android.dao.api.ParameterDao;
import com.ebraga.trackerclub.android.dao.api.UserDao;
import com.ebraga.trackerclub.android.dao.api.webservice.LoginLdapWSDao;
import com.ebraga.trackerclub.android.dao.entity.ParameterAndroid;
import com.ebraga.trackerclub.android.dao.entity.UserAndroid;
import com.ebraga.trackerclub.android.exception.BackofficeDBConnectionException;
import com.ebraga.trackerclub.android.exception.dao.BackofficeDaoException;
import com.ebraga.trackerclub.android.exception.dao.BackofficeIllegalArgumentDaoException;
import com.ebraga.trackerclub.android.exception.manager.BackofficeIllegalArgumentManagerException;
import com.ebraga.trackerclub.android.exception.manager.BackofficeLoginOffLineExpireException;
import com.ebraga.trackerclub.android.exception.manager.BackofficeManagerException;
import com.ebraga.trackerclub.android.manager.api.LoginManager;
import com.ebraga.trackerclub.android.util.DLog;
import com.ebraga.trackerclub.android.util.DateUtils;
import com.ebraga.trackerclub.android.util.ISmartServiceConstants;
import com.ebraga.trackerclub.android.util.enumeration.AndroidConfigurationParameterName;

public abstract class LoginManagerImpl implements LoginManager {
	
	protected UserDao userDao;
	protected LoginLdapWSDao loginLdapWSDao;
	protected ParameterDao parameterDao;
	
	protected void setParameterDao(ParameterDao parameterDao) {
		this.parameterDao = parameterDao;
	}

	protected void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
	protected void setLoginLdapWSDao(LoginLdapWSDao loginLdapWSDao) {
		this.loginLdapWSDao = loginLdapWSDao;
	}

	public void loginOnline(UserAndroid user) throws BackofficeManagerException {

		try {

			//Se o login é efetuado atualiza os dados do login na base local
			user.setLastLogin(new Date().getTime());
			long returnUpdate = userDao.update(user);
			if (returnUpdate == 0) {
				userDao.insert(user);
			}

		} catch (BackofficeDBConnectionException e) {
			DLog.e(e);
			throw new BackofficeManagerException(e.getMessage(), e);
		} catch (BackofficeDaoException e) {
			DLog.e(e);
			throw new BackofficeManagerException(e.getMessage(), e);
		} 

		
	}
	
	public void loginOffline(UserAndroid user) throws BackofficeManagerException {

		try {

			UserAndroid userOffLine = userDao.loginOffLine(user.getImei());

			if (userOffLine == null) {
				userDao.insert(user);
			} else {
				userDao.update(user);
			}

		} catch (BackofficeDBConnectionException e) {
			DLog.e(e);
			throw new BackofficeManagerException(e.getMessage(), e);
		} catch (BackofficeDaoException e) {
			DLog.e(e);
			throw new BackofficeManagerException(e.getMessage(), e);
		} 

	}

	public UserAndroid checkLastLogin() throws BackofficeManagerException {
		try {
			
			UserAndroid userAndroid = userDao.lastLogin();
			
			if (userAndroid != null) {
				
				ParameterAndroid android = parameterDao.getParameter(AndroidConfigurationParameterName.LOGIN_OFFLINE_AUTO.getName());
				long loginOffLineAuto = Long.parseLong(android.getValue());
				
				android = parameterDao.getParameter(AndroidConfigurationParameterName.LOGIN_OFFLINE_EXPIRE.getName());
				long loginOffLineExpire = Long.parseLong(android.getValue());					
				
				//Verifica se o último login está dentro de período aceito definido nos parametros.
				//Se não estiver faz o login On Line.
				if (DateUtils.diffBetweenDate(new Date(userAndroid.getLastLogin()), new Date(), Calendar.MINUTE) > loginOffLineExpire) {
					
					throw new BackofficeLoginOffLineExpireException(ISmartServiceConstants.ERROR_CODE.LOGIN_OFFLINE_EXPIRE);
					
				} 	
				
				if (DateUtils.diffBetweenDate(new Date(userAndroid.getLastLogin()), new Date(), Calendar.MINUTE) > loginOffLineAuto) {
					
					throw new BackofficeLoginOffLineExpireException(ISmartServiceConstants.ERROR_CODE.LOGIN_OFFLINE_AUTO);
					
				} 	
				
			} 
			
			return userAndroid;
		
		} catch (BackofficeDBConnectionException e) {
			DLog.e(e);
			throw new BackofficeManagerException(e.getMessage(), e);
		} catch (BackofficeDaoException e) {
			DLog.e(e);
			throw new BackofficeManagerException(e.getMessage(), e);
		} 
		
	}
	

	public UserAndroid lastLogin() throws BackofficeManagerException {
		try {
			
			UserAndroid userAndroid = userDao.lastLogin();
			
			return userAndroid;
		
		} catch (BackofficeDBConnectionException e) {
			DLog.e(e);
			throw new BackofficeManagerException(e.getMessage(), e);
		} catch (BackofficeDaoException e) {
			DLog.e(e);
			throw new BackofficeManagerException(e.getMessage(), e);
		} 
		
	}	
	
	public UserAndroid getUser(String login)
			throws BackofficeIllegalArgumentManagerException,
			BackofficeDBConnectionException , BackofficeManagerException {
		
		UserAndroid userA;
		
		if (login == null){
			throw new BackofficeIllegalArgumentManagerException("Usuario invalido");			
		}
		try{
			userA = userDao.getUser(login);
		}catch (BackofficeDBConnectionException db){
			DLog.e(db);
			throw new BackofficeDBConnectionException("Erro ao conectar banco de dados", db);
		}catch (BackofficeIllegalArgumentDaoException ie){
			DLog.e(ie);
			throw new BackofficeIllegalArgumentManagerException("Usuario invalido", ie);	
		}catch (BackofficeDaoException de){
			DLog.e(de);
			throw new BackofficeManagerException("Erro ao recuperar usuario", de);
		}
		
		return userA;
	}

	
}
